package com.codemonkey.lq.extend.excelverification;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.ibatis.io.Resources;

import com.codemonkey.lq.extend.excelverification.result.VerifyCellResult;
import com.codemonkey.lq.extend.excelverification.result.VerifyResultGroup;
import com.codemonkey.lq.extend.excelverification.result.VerifyRowResult;

/**
 * @author LQ
 *
 */
public class VerifyWorker {
	private Config fieldVerifyConfig;

	public VerifyWorker(String confiFilePath) {
		InputStream configIS = null;
		try {
			configIS = Resources.getResourceAsStream(confiFilePath);
		} catch (IOException e) {
			e.printStackTrace();
		}

		if (null == configIS) {
			return;
		}

		commonConstruct(configIS);
	}
	
	public VerifyWorker(InputStream configIS) {
		commonConstruct(configIS);
	}	
	
	private void commonConstruct(InputStream configIS){
		fieldVerifyConfig = new ConfigBuilder(configIS).build();
	}

	public VerifyResultGroup work(List<Map<String, Object>> dataSourceNeedVerify) {
		assert null != dataSourceNeedVerify;
		assert 0 < dataSourceNeedVerify.size();

		VerifyResultGroup verifyResultGroup = new VerifyResultGroup();
		for (int i = 0; i < dataSourceNeedVerify.size(); i++) {
			Map<String, Object> rowNeedVerify = dataSourceNeedVerify.get(i);
			VerifyRowResult verifyRowResult = verifyRow(rowNeedVerify, i);
			verifyResultGroup.addVerifyRowResult(verifyRowResult);
		}

		return verifyResultGroup;
	}

	private VerifyRowResult verifyRow(Map<String, Object> rowNeedVerify, int index) {
		VerifyRowResult verifyRowResult = new VerifyRowResult(index);

		for (Map.Entry<String, Object> cellNeedVerify : rowNeedVerify.entrySet()) {
			VerifyCellResult verifyCellResult = verifyCell(cellNeedVerify, rowNeedVerify);
			verifyRowResult.addVerifyCellResult(verifyCellResult);
		}

		return verifyRowResult;

	}

	private VerifyCellResult verifyCell(Entry<String, Object> cellNeedVerify,
			Map<String, Object> rowNeedVerify) {
		final String fieldName = cellNeedVerify.getKey();
		final Object fieldVal = cellNeedVerify.getValue();

		CellContext cellContext = new CellContext(-1, fieldName, fieldVal, rowNeedVerify);

		Verifier cellVerifier = fieldVerifyConfig.findVerifier(fieldName);
		if (null == cellVerifier) {
			// 不需要校验
			return VerifyCellResult.noNeedVerify(cellContext.getCellName());
		}

		boolean isPass = cellVerifier.verify(cellContext);
		VerifyCellResult result = new VerifyCellResult(isPass, cellContext.getCellName());
		result.setVal(cellContext.getCellVal());
		result.setIndex(cellContext.getCellIndex());
		if (isPass) {
			// NO OP
		} else {
			result.setDetail(cellContext.getFailMsg());
			result.setPrompt(cellVerifier.getReadableFailMsg(cellContext));
		}

		return result;

	}

}
